package com.xrh.xdemo.service.interceptors;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.xrh.core.annotation.InterfacePermission;
import com.xrh.core.bean.CommonResult;
import com.xrh.core.enums.ResultCodeEnum;
import com.xrh.xdemo.api.dto.extend.SysUserDetailDTO;
import com.xrh.xdemo.service.utils.LoginUtils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
	
	/**
     * 在请求处理之前进行调用（Controller方法调用之前）
     */
	@Override
    public boolean preHandle(HttpServletRequest request , HttpServletResponse response, Object handler) throws Exception {
    	
    	 try {
    		 	
    		 	//从header获取token
    		 	String token = request.getHeader("token");
    		 	
    		 	if(StrUtil.isBlank(token)) {
    		 		outErrorMsg(response , CommonResult.failed(ResultCodeEnum.UNAUTHORIZED));
    		 		return false;
    		 	}
    		 	
    		 	SysUserDetailDTO user = LoginUtils.getUser();
    			
    			//不存在登录信息返回false
    			if(user == null){
    				outErrorMsg(response , CommonResult.failed(ResultCodeEnum.UNAUTHORIZED));
    		 		return false;
    		 	}
    			
    			if(user.isAdmin()) 
    				return true;
    			
    			//是否有接口权限
    			boolean hasInterfacePermission =  checkInterfacePermission(user , request.getRequestURI() , (HandlerMethod) handler);
    			
    			if(!hasInterfacePermission) {
    				outErrorMsg(response , CommonResult.failed(ResultCodeEnum.FORBIDDEN));
    				return false;
    			}
    			
    			return true;
    		 
		} catch (Exception e) {
			log.error("拦截器preHandle异常 : ", e); 
			outErrorMsg(response, CommonResult.failed(ResultCodeEnum.UNAUTHORIZED));
			return false;
		}
    	 
    }
	
	/**
	 * @function 检测接口权限
	 * @author 肖荣辉
	 * @date 2023年12月21日
	*/
	public boolean checkInterfacePermission(SysUserDetailDTO user , String uri , HandlerMethod handlerMethod) {
		
		//验证接口权限
		Method method = handlerMethod.getMethod();
		
		//是否有接口权限注解 , 没有则直接拥有该接口权限
		if(!method.isAnnotationPresent(InterfacePermission.class))
			return true;
		
		InterfacePermission interfacePermission = method.getAnnotation(InterfacePermission.class);
		
		String interfaceUri = interfacePermission.value();
		
		//判断访问的接口是否是当前接口地址 , 如果不是 , 则直接返回true
		if(!interfaceUri.equals(uri))
			return true;
		
		//判断当前用户是否拥有当前接口地址
		return user.hasInterfacePermission(interfaceUri);
			
	}
	
	
	
	/**
     * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
    
    /**
     * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    	
    }
	
	/**
	 * @function 输出错误信息
	 * @param response
	 * @author 数垚科技
	 * @throws IOException 
	 * @date 2022年9月5日
	*/
	private void outErrorMsg(HttpServletResponse response , CommonResult<?> rst) throws IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.append(JSONUtil.toJsonStr(rst));
		out.flush();
	}

}